﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace testUI
{
    public partial class Form1_r1 : Form
    {
        // METHODS IMPORTED FROM DLL
        // For JSTEG, F3, F4, F5
        // under x86, int = long = Int32
        public const String DLLPATH = "tools\\tools.dll";
        [DllImport(DLLPATH, EntryPoint = "predictOne", CallingConvention = CallingConvention.Cdecl)]
        public static extern Int32 predictOne(StringBuilder model_name, StringBuilder feature_name, Int32 feature_len, StringBuilder output_name);

        // For Detect
        // TODO
        public const String DLLPATH2 = "steganalysis\\steganalysis.dll";
        [DllImport(DLLPATH2, EntryPoint = "markov", CallingConvention = CallingConvention.Cdecl)]
        public static extern Int32 markov(StringBuilder picname, StringBuilder txtname);
        [DllImport(DLLPATH2, EntryPoint = "histogram", CallingConvention=CallingConvention.Cdecl)]
        public static extern Int32 histogram(StringBuilder picname, StringBuilder txtname);

        // GUI
        private string inpath3 = "";
        private string modpath3 = "";
        Int32 LEN_MARKOV = 98;
        Int32 LEN_HIST = 129;
        public const string MODEL_PATH = "models\\";

        public Form1_r1()
        {
            InitializeComponent();
        }

        private void btn_picsel3_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "JPEG File|*.jpg|All files (*.*)|*.*";
            openFileDialog1.Title = "Select a JPEG File";
            openFileDialog1.CheckFileExists = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.inpath3 = openFileDialog1.FileName;
                Console.WriteLine("Load image: " + this.inpath3);
                Image img = Image.FromFile(inpath3);
                Image bitmap = new Bitmap(img);
                img.Dispose();
                this.pbox_in3.Image = bitmap;
            }
        }

        private void btn_exit3_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void rbtn_hist1d_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_feature.Name = "hist1d";
        }

        private void rbtn_markov_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_feature.Name = "markov";
        }

        private void rbtn_jsteg3_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_3.Name = "Jsteg";
            this.btn_modsel3.Enabled = false;
        }

        private void rbtn_f33_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_3.Name = "F3";
            this.btn_modsel3.Enabled = false;
        }

        private void rbtn_f43_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_3.Name = "F4";
            this.btn_modsel3.Enabled = false;
        }

        private void rbtn_f53_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_3.Name = "F5";
            this.btn_modsel3.Enabled = false;
        }

        private void rbtn_other3_CheckedChanged(object sender, EventArgs e)
        {
            this.gbox_3.Name = "other";
            this.btn_modsel3.Enabled = true;
        }

        private void btn_modsel3_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "SVM Model File|*.model|All files (*.*)|*.*";
            openFileDialog1.Title = "Select an SVM Model";
            openFileDialog1.CheckFileExists = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.modpath3 = openFileDialog1.FileName;
            }
        }

        private void btn_feaext3_Click(object sender, EventArgs e)
        {
            Int32 histlen;
            string tempfname1 = System.IO.Path.GetTempFileName();
            if (this.inpath3.Equals(""))
            {
                MessageBox.Show("错误：未选择图像！");
                return;
            }
            StringBuilder iname1 = new StringBuilder(this.inpath3);
            StringBuilder oname1 = new StringBuilder(tempfname1);
            long retval = -1;
            this.tbx_out3.Clear();
            switch (this.gbox_feature.Name)
            {
                case "markov":
                    retval = markov(iname1, oname1);
                    histlen = LEN_MARKOV;
                    break;
                case "hist1d":
                    retval = histogram(iname1, oname1);
                    histlen = LEN_HIST;
                    break;
                default:
                    MessageBox.Show("错误：未选择特征类型！");
                    return;
            }
            Console.WriteLine("Return value = " + retval);
            StringBuilder modname = null;
            switch (this.gbox_3.Name)
            {
                case "Jsteg":
                case "F3":
                case "F4":
                case "F5":
                    switch (this.gbox_feature.Name)
                    {
                        case "hist1d":
                            modname = new StringBuilder(Application.StartupPath + '\\'+MODEL_PATH + this.gbox_3.Name + "_h.model");
                            break;
                        case "markov":
                            modname = new StringBuilder(Application.StartupPath + '\\'+MODEL_PATH + this.gbox_3.Name + "_m.model");
                            break;
                        default:
                            // not reachable?                            
                            break;
                    }
                    break;
                case "other":
                    modname = new StringBuilder(this.modpath3);
                    break;
                default:
                    MessageBox.Show("错误：未选择检测模型！");
                    return;
            }
            // READ OUTPUT FILE
            if (retval < 0)
            {
                MessageBox.Show("特征提取发生错误！");
                return;
            }
            Console.WriteLine("Use model file : " + modname);
            retval = -1;// negative: error, [0, 1, ...] : classes
            StringBuilder iname2 = oname1;
            String tempfile2 = System.IO.Path.GetTempFileName();
            StringBuilder oname2 = new StringBuilder(tempfile2);
            retval = predictOne(modname, iname2, histlen, oname2);
            Console.WriteLine("Return value = " + retval.ToString());
            if (retval < 0)
            {
                if (retval == -2) 
                    MessageBox.Show("无法载入检测模型");
                else
                    MessageBox.Show("SVM分类发生错误！");
                return;
            }
            else {
                MessageBox.Show("Finished!!!");
                String msg = "";
                //"Class is " + retval.ToString() + "\r\n";
                if (retval == 0)
                    msg = msg + "分类：未隐藏信息\r\n";
                else
                    msg = msg + "分类：含隐藏信息\r\n";
                StreamReader sr = new StreamReader(tempfile2);
                String s = sr.ReadLine();
                String s1 = sr.ReadToEnd();
                sr.Close();
                msg=msg+"准确率："+s1;
                this.tbx_out3.Text = msg;
            }
        }
    }

}
